#include <atomic>
#include <bitset>
#include <cstdint>
#include <iostream>


void testBitset() {
    [[maybe_unused]]  constexpr int isHungry        { 0 };
    [[maybe_unused]]  constexpr int isSad           { 1 };
    [[maybe_unused]]  constexpr int isMad           { 2 };
    [[maybe_unused]]  constexpr int isHappy         { 3 };
    [[maybe_unused]]  constexpr int isLaughing      { 4 };
    [[maybe_unused]]  constexpr int isAsleep        { 5 };
    [[maybe_unused]]  constexpr int isDead          { 6 };
    [[maybe_unused]]  constexpr int isCrying        { 7 };

    std::bitset<8> me { 0b0000'0101 };
    me.set(isHappy);        // Set bit position 3 to 1: 0000 1101
    me.flip(isLaughing);    // Flip bit 4: 0001 1101
    me.reset(isLaughing);   // Set bit 4 back to 0: 0000 1101

    std::cout << "All the bits: " << me << '\n';
    std::cout << "I am happy: " << me.test(isHappy) << '\n';
    std::cout << "I am laughing: " << me.test(isLaughing) << '\n';

    std::cout << me.size() << " bits are in the bitset\n";
    std::cout << me.count() << " bits are set to true\n";
    std::cout << std::boolalpha;
    std::cout << "All bits are true: " << me.all() << '\n';
    std::cout << "Some bits are true: " << me.any() << '\n';
    std::cout << "No bits are true: " << me.none() << '\n';
}


std::bitset<4> rotl(std::bitset<4> bits) {
#if 0
    const bool leftBit { bits.test(3) };
    bits <<= 1;
    if (leftBit) {
        bits.set(0);
    }
    return bits;
#else
    return (bits << 1) | (bits >> 3);
#endif
}


void testBitwiseOperator() {
    std::bitset<4> bits1{ 0b0001 };
    std::cout << rotl(bits1) << '\n';

    std::bitset<4> bits2{ 0b1001 };
    std::cout << rotl(bits2) << '\n';
}


void getRgbaValue() {
    constexpr std::uint32_t redBits{ 0xFF000000 };
    constexpr std::uint32_t greenBits{ 0x00FF0000 };
    constexpr std::uint32_t blueBits{ 0x0000FF00 };
    constexpr std::uint32_t alphaBits{ 0x000000FF };

    std::cout << "Enter a 32-bit RGBA color value in hexadecimal (e.g. FF7F3300): ";
    std::uint32_t pixel {};
    std::cin >> pixel;

    const std::atomic_uint8_t red { static_cast<std::uint8_t>((pixel & redBits) >> 24) };
    const std::atomic_uint8_t green { static_cast<std::uint8_t>((pixel & greenBits) >> 16) };
    const std::atomic_uint8_t blue { static_cast<std::uint8_t>((pixel & blueBits) >> 8) };
    const std::atomic_uint8_t alpha { static_cast<std::uint8_t>(pixel & alphaBits) };

    std::cout << "Your color contains: \n";
    std::cout << std::hex;

    std::cout << static_cast<int>(red)      << " red\n";
    std::cout << static_cast<int>(green)    << " green\n";
    std::cout << static_cast<int>(blue)     << " blue\n";
    std::cout << static_cast<int>(alpha)    << " alpha\n";
}


int printBits(int digital, int pow, int index, int* array) {
    // 128 64 32 16 8 4 2 1
    // 1111'1111
    if (digital >= pow) {
        array[index] = 1;
        digital -= pow;
    } else {
        array[index] = 0;
    }

    // std::cout << "digital: " << digital << ", pow: " << pow << ", index: " << index << ", res: " << array[index] << '\n';

    return digital;
}

void printUint8DigitalUseBinFmt() {
    std::cout << " Enter a ditigal(0~255): ";
    int digital {};
    std::cin >> digital;

    if (digital > 255) {
        digital = 255;
    }

    if (digital < 0) {
        digital = 0;
    }

    int result[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    digital = printBits(digital, 128, 0, result);
    digital = printBits(digital, 64, 1, result);
    digital = printBits(digital, 32, 2, result);
    digital = printBits(digital, 16, 3, result);
    digital = printBits(digital, 8, 4, result);
    digital = printBits(digital, 4, 5, result);
    digital = printBits(digital, 2, 6, result);
    digital = printBits(digital, 1, 7, result);

    for (int i = 0; i < 8; ++i) {
        std::cout << result[i];
    }
    std::cout << '\n';
}
